package com.kris;

import java.io.FileOutputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.WorkbookUtil;

/**
 * 员工加班统计表(平时和周末独立统计)
 *
 * @author Kris Zhang
 */
public class WorkOverTimeReport extends Report {

    final String title = "加班统计表";
    final String[] header = {"姓名", "平时加班时长", "节假日加班时长", "合计"};

    Map<String, EmployeeAttendRecord> records;
    List<String> employeeList;
    private final List<Date> holidays;
    private final List<Date> excludeHolidays;

    //此报表的文件名称
    String filename = null;
    String sheetName = null;

    WorkOverTimeReport(String excelFilename,
            List<String> employeeList,
            Map<String, EmployeeAttendRecord> records,
            List<Date> holidays,
            List<Date> excludeHolidays) {
        this.filename = excelFilename;
        this.employeeList = employeeList;
        this.records = records;
        this.sheetName = "sheet1";
        this.holidays = holidays;
        this.excludeHolidays = excludeHolidays;
    }

    @Override
    public void make() throws Exception {
        // 新建一个excel
        Workbook wb = new HSSFWorkbook();

        //工作簿
        String safeName = WorkbookUtil.createSafeSheetName(this.sheetName);
        Sheet sheet = wb.createSheet(safeName);

        // 建立第一个行， 把表的标题放到这里
        Row firstRow = sheet.createRow((short) 0);
        CellStyle titleStyle = wb.createCellStyle();
        titleStyle.setAlignment(HorizontalAlignment.CENTER); // 设置字体居中显示
        titleStyle.setFont(createFontArial18(wb));
        Cell titleCell = firstRow.createCell(0);
        titleCell.setCellValue(title);
        titleCell.setCellStyle(titleStyle);

        // 合并第一行表格
        sheet.addMergedRegion(new CellRangeAddress(
                0, //first row (0-based)
                0, //last row  (0-based)
                0, //first column (0-based)
                3 //last column  (0-based)
        ));

        // 建立表头样式, 设置背景颜色
        CellStyle headerStyle = wb.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headerStyle.setAlignment(HorizontalAlignment.CENTER); // 设置字体居中显示
        headerStyle.setFont(createFontArial14(wb));

        // 建立第2行, 设置表头
        Row secondRow = sheet.createRow((short) 1);
        for (int j = 0; j < header.length; j++) {
            Cell headerCell = secondRow.createCell(j);
            headerCell.setCellValue(header[j]);
            headerCell.setCellStyle(headerStyle);
        }

        // ---------------------------------------------
        //                表格数据
        // ---------------------------------------------
        // 表格数据格式
        CellStyle dataStyle = wb.createCellStyle();
        dataStyle.setFont(createFontArial12(wb));

        int rowIndex = 2; //员工数据开始的行数
        // 获取所有员工名单
        // 循环处理每个员工的时间
        for (int i = 0; i < employeeList.size(); i++) {
            String name = employeeList.get(i);

            // 获取此员工所有的加班信息记录
            EmployeeAttendRecord em = records.get(name);
            if (em == null) {
                // 忽略不存在考勤记录的员工
                continue;
            }

            long workingDayOverTime = 0;
            long hoildayOverTime = 0;

            List<EmployeeWorkTime> worktimes = em.getWorkTimeRecords();
            for (int k = 0; k < worktimes.size(); k++) {
                EmployeeWorkTime employeeWorkTime = worktimes.get(k);

                if (DateUtil.isWeekendOrHoliday(employeeWorkTime.getBeginTime(),
                        this.holidays,
                        this.excludeHolidays)) {
                    long overtime = calculateHolidayOverTime(
                            employeeWorkTime.getBeginTime(),
                            employeeWorkTime.getEndTime());
                    hoildayOverTime += overtime;

                } else {

                    long overtime = calculateWorkOverTime(
                            employeeWorkTime.getBeginTime(),
                            employeeWorkTime.getEndTime());
                    workingDayOverTime += overtime;
                }

            }//end for

            createRow(sheet, rowIndex, name, workingDayOverTime, hoildayOverTime, dataStyle);
            rowIndex++;

        } // end for

        FileOutputStream fileOut = new FileOutputStream(this.filename);
        wb.write(fileOut);
        fileOut.close();

    }

    void createRow(Sheet sheet, int rowIndex, String employeeName,
            long overtime, long holidayOverTime, CellStyle dataStyle) {
        // 建立一个行
        Row row = sheet.createRow(rowIndex);
        Cell cell0 = row.createCell(0);
        // 员工姓名
        cell0.setCellValue(employeeName);
        cell0.setCellStyle(dataStyle);
        // 平时加班时长
        Cell cell1 = row.createCell(1);
        cell1.setCellValue(DateUtil.toHumanReadable(overtime));
        cell1.setCellStyle(dataStyle);
        // 节假日加班时长
        Cell cell2 = row.createCell(2);
        cell2.setCellValue(DateUtil.toHumanReadable(holidayOverTime));
        cell2.setCellStyle(dataStyle);
        // 合计
        Cell cell3 = row.createCell(3);
        cell3.setCellValue(DateUtil.toHumanReadable(overtime + holidayOverTime));
        cell3.setCellStyle(dataStyle);
    }

    /**
     * 平时加班=下班时间-上班时间-9小时<br>
     * 返回加班时长的毫秒数
     *
     * @param beginTime
     * @param endTime
     * @return
     */
    protected long calculateWorkOverTime(Date beginTime, Date endTime) {
        //没有打卡的，都不算加班
        if (beginTime == null || endTime == null) {
            return 0;
        }

        // 9个小时以上都是加班
        long workOvertime = endTime.getTime() - beginTime.getTime() - NINE_HOUR;

        if (workOvertime < 0) {
            return 0;
        }

        return workOvertime;
    }

    /**
     * 计算周末加班时间
     *
     * @param beginTime
     * @param endTime
     * @return
     */
    private long calculateHolidayOverTime(Date beginTime, Date endTime) {
        //没有打卡的，都不算加班
        if (beginTime == null || endTime == null) {
            return 0;
        }

        // 所有来的时间都是加班
        return endTime.getTime() - beginTime.getTime();

    }

}
